package nickthissen.iracing.parsing;

import java.util.ArrayList;

import nickthissen.iracing.common.ServiceLogging;
import nickthissen.iracing.datamodels.*;
import nickthissen.iracing.common.Error;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;


public class ForumListParser extends Parser
{
    public Context context;

	@Override
	protected String getLogName() {
		return "ForumListParser";
	}

    @Override
    protected Result createDefaultResultObject()
    {
        Result result = new Result();
        ForumList forumlist = new ForumList();
        forumlist.Forums = new ArrayList<Forum>();
        result.Object = forumlist;
        result.Message = "Error parsing forum list.";
        return result;
    }

	@Override
	public Result doParse(String source)
	{
		Result result = new Result();
		ForumList forumlist = new ForumList();
		forumlist.Forums = new ArrayList<Forum>();

        log("Start jsoup parsing forumlist source.");

        if (logLarge(context, source))
            log("Source logged.");
        else
            log("Source logging disabled.");

        Document doc = Jsoup.parse(source);
        log("Finished jsoup parsing source.");

        Element tableNode = doc.getElementById("forum");
        if (tableNode == null)
            log("Tablenode was null.");
        else
            log("Tablenode:" + tableNode.html());

        String category = "";

        // Loop through rows of the table
        ArrayList<Element> rows = Parsing.selectChildren(tableNode.select("tbody").first(), "tr");
        for (int trIndex = 0; trIndex < rows.size(); trIndex++)
        {
            Element tr = rows.get(trIndex);

            boolean rowIsParsed = false;

            // The top row (column headers) is the only row with attributes - skip it
            if (tr.attributes().size() > 0) continue;

            log("Start parsing table row.");

            // Loop through columns
            ArrayList<Element> columns = Parsing.selectChildren(tr, "td[class]");// tr.select("td[class]");
            for (int tdIndex = 0; tdIndex < columns.size(); tdIndex++)
            {
                Element td = columns.get(tdIndex);

                // If row already parsed, skip it
                if (rowIsParsed) continue;

                log("Start parsing table column.");

                String attr = td.attr("class");

                log("class attr = " + attr);

                if (attr != null && !attr.trim().equals(""))
                {
                    if (attr.equals(StringConstants.CategoryClass))
                    {
                        // Remember this category
                        category = td.text();

                        Forum forum = new Forum();
                        forum.IsCategoryHeader = true;
                        forum.Category = category;
                        forumlist.Forums.add(forum);
                    }
                    else
                    {
                        // Parse this row as a forum
                        Forum forum = parseForum(tr);
                        if (forum != null)
                        {
                            forum.Category = category;
                            forumlist.Forums.add(forum);
                        }

                        // Finished parsing row
                        rowIsParsed = true;
                    }
                }
            }
        }

        parsePms(doc, forumlist);

        result.Success = true;

		result.Object = forumlist;		
		return result;
	}

    private void parsePms(Document doc, ForumList forumlist)
    {
        try
        {
            Elements newPmLinks = doc.select("div[id=newMessages] > a");
            if (newPmLinks.size() > 0)
            {
                Element link = newPmLinks.first();
                Element strong = link.select("strong").first();
                String count = strong.text().trim();
                log("Count string: " + count);
                if (TextUtils.isDigitsOnly(count))
                {
                    forumlist.NewPmCount = Integer.parseInt(count);
                }
            }
        }
        catch (Exception ex)
        {
            log("Error parsing PM count: " + ex.getMessage());
        }
    }
	
	private Forum parseForum(Element node)
	{
		Forum forum = new Forum();
	
		// Find the 5 childnodes		
        ArrayList<Element> nodeElements = Parsing.selectChildren(node, "td[class]"); // node.select("td[class]");
		Node[] nodes = nodeElements.toArray(new Node[nodeElements.size()]);
		
		if (nodes.length != 5) return null;
		
		Node iconNode = nodes[0];
		parseIcon(forum, iconNode);
		
		Node topicNode = nodes[1];
		Node linkNode = topicNode.childNode(0);
		forum.Url = linkNode.attr("href");
		
		String name = Parsing.getFilenameWithoutExtension(forum.Url);
		
		log("URL: " + forum.Url);
		log("Name: " + name);

		forum.Id = Integer.parseInt(name);
		
		//TODO: De-entitize
		forum.Title = ((TextNode)linkNode.childNode(0)).text();
		
		parseTopicsPosts(forum, nodes);
		parseLastMessage(forum, nodes[4]);
		
		return forum;
	}
	
	private void parseIcon(Forum forum, Node node)
	{
		Node imgNode = node.childNode(0);
		if (imgNode == null || !imgNode.nodeName().equals("img")) return;
		
		String path = imgNode.attr("src");
		String name = Parsing.getFilenameWithoutExtension(path);
		if (name != null) forum.IconName = name.toLowerCase().trim();
	}
	
	private static void parseTopicsPosts(Forum forum, Node[] nodes)
	{
		
	}
	private static void parseLastMessage(Forum forum, Node node)
	{
		
	}
}
